﻿using System;
using System.Data;
//Using PCS'namespaces
using PCSComPayroll.DS;
using System.Collections.Specialized;

namespace PCSComPayroll.BO
{
    public class PayrollReportBO
    {
        PayrollReportDS objds = new PayrollReportDS();
        public DataTable ExecuteReport(string pstrProductID)
        {
            DataTable dtbReportData = new DataTable();
            int intProductID = Convert.ToInt32(pstrProductID);

            DataTable dtbTop = new DataTable("BaoCaoDinhMuc");
            dtbTop = objds.GetOneItem(intProductID);
            DataTable dtbAllChild = objds.GetAllItems();
            dtbReportData = dtbTop.Clone();
            foreach (DataRow drowData in dtbTop.Rows)
                BuildData(dtbReportData, dtbAllChild, drowData, 0);
            // add number list
            dtbReportData = AddNumberedListToDataTable(dtbReportData);
            return dtbReportData;
        }
        private DataRow[] GetChild(DataTable pdtbAllChilds, int pintParentID)
        {
            return pdtbAllChilds.Select("ParentID = '" + pintParentID.ToString() + "'");
        }
        private void BuildData(DataTable pdtbData, DataTable pdtbAllChild, DataRow pdrowNew, int pintLevel)
        {
            DataRow drowItem = pdtbData.NewRow();
            foreach (DataColumn dcolData in pdtbData.Columns)
                drowItem[dcolData.ColumnName] = pdrowNew[dcolData.ColumnName];
            drowItem["Level"] = pintLevel;
            pdtbData.Rows.Add(drowItem);
            // get child
            DataRow[] drowsChild = GetChild(pdtbAllChild, int.Parse(drowItem["ProductID"].ToString()));
            foreach (DataRow drowChild in drowsChild)
                BuildData(pdtbData, pdtbAllChild, drowChild, pintLevel + 1);
        }

        private DataTable AddNumberedListToDataTable(DataTable pdtb)
        {
            DataTable dtbRet = pdtb.Copy();

            DataColumn odcol = new DataColumn("NumberedList");
            odcol.DataType = typeof(string);
            odcol.DefaultValue = "";
            dtbRet.Columns.Add(odcol);

            int[] arriInputLevel = ExtractArrayOfLevelFromDataTable(pdtb);
            StringCollection arrNumberedList = GetNumberedListForBOMProduct(arriInputLevel, 0, ".");

            int intCount = 0;
            foreach (DataRow row in dtbRet.Rows)
            {
                string strNumber = arrNumberedList[intCount];
                string strPartNo = row["Part No."].ToString();
                row["NumberedList"] = strNumber;
                // indent the part no following the level
                int intLevel = int.Parse(row["Level"].ToString());
                for (int i = 0; i < intLevel; i++)
                    strPartNo = "- " + strPartNo;
                row["Part No."] = strPartNo;
                intCount++;
            }
            return dtbRet;
        }

        //**************************************************************************              
        ///    <summary>
        ///       Generate a list of number string (format as 1.1.2.3, ...) to append to BOM product report
        ///       Use only by AddNumberedListToDataTable() method
        ///    </summary>
        ///    <Inputs>
        ///       
        ///    </Inputs>
        ///    <Outputs>
        ///       
        ///    </Outputs>
        ///    <Returns>
        ///       
        ///    </Returns>
        ///    <Authors>
        ///       ThachNN
        ///    </Authors>
        ///    <History>
        ///       21-Sep-2005
        ///    </History>
        ///    <Notes>
        ///    </Notes>
        //**************************************************************************
        public static StringCollection GetNumberedListForBOMProduct(int[] parriInput,
                                                                    int pintRootNumber,
                                                                    string pstrDeli)
        {
            #region DEFINE Variables

            StringCollection arrRet = new StringCollection();
            int intRecordCount = parriInput.Length;
            StringCollection arrParentString = new StringCollection();
            for (int intCounter = 0; intCounter < intRecordCount + 1; intCounter++)
                arrParentString.Add("");
            int[] arriLevelHit = new int[intRecordCount + 1];

            #endregion

            //int intPrev = pintRootNumber; // in start phase, iRootNumber is iPrev
            foreach (int i in parriInput)
            {
                string strOut = "";
                /// Update level hit count == active running number of last index
                (arriLevelHit[i])++; // increase the hit count  of level i
                arriLevelHit[i + 1] = 0; // reset hit count of level i+1 to ZERO

                if (i == pintRootNumber) // if the level is restart to iRootNumber
                {
                    // level 0, not exist
                    // Parent string of level iRootNumber, alway = ""
                    // strOut always = "1"
                    arrParentString[i] = "";
                    strOut = "1";
                }
                else
                {
                    strOut = arrParentString[i] + pstrDeli + arriLevelHit[i];
                    if (strOut.StartsWith("."))
                        strOut = strOut.Remove(0, 1);
                }
                //intPrev = i;
                arrParentString[i + 1] = strOut;
                arrRet.Add(strOut);
            }
            return arrRet;
        }

        //**************************************************************************              
        ///    <summary>
        ///       Return array of int, contain level columm (named "Level") from DataTable
        ///       Use only by AddNumberedListToDataTable() method
        ///    </summary>
        ///    <Inputs>
        ///       DataTable contain column "Level"
        ///    </Inputs>
        ///    <Outputs>
        ///       Array of int, contain value from "Level" data column
        ///    </Outputs>
        ///    <Returns>
        ///       
        ///    </Returns>
        ///    <Authors>
        ///       ThachNN
        ///    </Authors>
        ///    <History>
        ///       21-Sep-2005
        ///    </History>
        ///    <Notes>
        ///    </Notes>
        //**************************************************************************
        public static int[] ExtractArrayOfLevelFromDataTable(DataTable pdtb)
        {
            int[] arrintRet = new int[pdtb.Rows.Count];
            int intCount = 0;
            foreach (DataRow row in pdtb.Rows)
            {
                arrintRet[intCount] = int.Parse(row["Level"].ToString());
                intCount++;
            }
            return arrintRet;
        }

    }
}
